package com.groupa.project1.database;


import com.groupa.project1.chat.InstantMessageClass;
import com.groupa.project1.chat.ToolsClass;
import com.groupa.project1.database.interfaces.DBManager;
import com.groupa.project1.database.interfaces.DBAction;
import com.groupa.project1.database.interfaces.DBActionResult;
import com.groupa.project1.database.XmlDbDataSourceClass;
import com.groupa.project1.database.interfaces.*;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import java.util.Properties;
import java.util.logging.Level;
import org.exist.xmldb.XQueryService;

public class DBManagerClass implements DBManager{

    private static XmlDbDataSourceClass DS;
    private static Logger log;
    private static DBManager DBM;
    private static Properties Prop;
    private static Properties Actions;
    
    private DBManagerClass(){
        Prop = InstantMessageClass.getPropertiesStatic();
        Actions = InstantMessageClass.getActionsStatic();
        DS = new XmlDbDataSourceClass(Prop);
        log = InstantMessageClass.getLog();
  
    }
    
     public synchronized static DBManager GetInstance(){
        /* Usamos el patron de diseño singelton */
        if(DBM == null){
            DBM = new DBManagerClass(); 
        }       
        return DBM;
    }
    public Logger getLog(){
            return log;
        }   
 
    public DBActionResult execute(DBAction aDBAction) {
          
        DBActionResult result = new DBActionResultClass();
        List <Object> ResultList = new ArrayList <Object>();
         
        Collection c = null;
        XQueryService Q = null;
        XUpdateQueryService U = null;
        ResourceSet R;

        Object[] parameter;
        String actionId;
        String QUERY;
        String FinalQuery;
         
        try { 
            /*Obtenemos la coleción obtenida en XmlDbDataSourceClass*/
            c = DS.getCollection();
       
        }catch (XMLDBException ex) {
            result.setErrorMsg("Error al obtener la coleción!");
            result.setException(ex);
            result.setOk(false);
        }

        /* Obtenemos el tipo de query que queremos realizar */ 
        actionId  = aDBAction.getActionId();
        log.info("Action id:"+actionId);
        /* Obtenemos el archivo de propiedades */
        ToolsClass Tools = new ToolsClass(log);
       
         
        if((actionId.substring(0,1)).equalsIgnoreCase("Q")){ /* Es una query */
             
            try {  
              /* Obtenemos la query a realizar */
              QUERY = Actions.getProperty(actionId);
              /* Inicializamos el queryservice*/
              Q = (XQueryService) c.getService("XQueryService","1.0");
              /* Obtenemos los parametros de la query */
              parameter = aDBAction.getParameters();
               /* Le introducimos los parametros a la query */
              FinalQuery = MessageFormat.format(QUERY, parameter);      
              /* Ejecutamos la finalquery i la guardamos en un ResourceSet */
              R = Q.query(FinalQuery);
              /* Devolvemos el resultado */  
              log.info("Query realizada:"+FinalQuery);
              
              ResourceIterator i = R.getIterator();
            
                 if((actionId.substring(2,3)).equalsIgnoreCase("p")){ /* Es una foto */
            
                        Photo Picture;
                        String title="",path="",date="",author="",description="";

                        while(i.hasMoreResources()) {

                            Resource r = i.nextResource();
                            String line = (String)r.getContent();

                            if(line.indexOf("<Title>") != -1){   
                                title = line.substring(line.indexOf("<Title>")+7, line.indexOf("</Title>"));   
                            }
                            if(line.indexOf("<Path_Thumbnail>") != -1){ 
                                path = line.substring(line.indexOf("<Path_Thumbnail>")+16, line.indexOf("</Path_Thumbnail>"));
                            }
                            if(line.indexOf("<Date>") != -1){ 
                                date = line.substring(line.indexOf("<Date>")+6, line.indexOf("</Date>"));
                            }
                            if(line.indexOf("<Description>") != -1){ 
                                description = line.substring(line.indexOf("<Description>")+13, line.indexOf("</Description>"));
                            }
                            if(line.indexOf("<ID_user>") != -1){ 
                                author = line.substring(line.indexOf("<ID_user>")+9, line.indexOf("</ID_user>"));
                            }
                        Picture = new PhotoClass(path, date, author);
                        Picture.setTitle(title);
                        Picture.setDescription(description);

                        ResultList.add(Picture);
                        
                        }
                       /* Lo encapsulamos en el resultado */
                        result.setResult(ResultList);

                        /* Resultado correcto*/
                        result.setOk(true);
                }  
            
                if((actionId.substring(2,3)).equalsIgnoreCase("n")){ /* Es una noticia*/
                    
                        News N;
                        String title="", paragraph[]=null, picture_path[]=null;

                        while(i.hasMoreResources()) {

                            Resource r = i.nextResource();
                            String line = (String)r.getContent();
                            /* Obtenemos el titulo */
                            if(line.indexOf("<title>") != -1){   
                                title = line.substring(line.indexOf("<title>")+7, line.indexOf("</title>"));   
                            }
                            
                            String lastIndex = line;
                            String lastIndex2 = line;
                            String line2 = line;
                            
                            int count = 0;
                            /* Obtenemos el tamaño del array de parragrafos */
                            while (lastIndex.indexOf("<paragraph>") > -1) {
                                   lastIndex = line.substring(lastIndex.indexOf("<paragraph>")+"<paragraph>".length(),lastIndex.length());
                                   count++;
                            }
                           
                            paragraph = new String[count]; 
                            /* Rellenamos el array de parragrafos con los parrafos*/
                            for(int e = 0; e<paragraph.length; e++){
                                   paragraph[e] = line.substring(line.indexOf("<paragraph>")+11, line.indexOf("</paragraph>"));  
                                   line = line.substring((line.indexOf("</paragraph>")+12),line.length());
                           }
                           
                            int count2 = 0;
                            /* Obtenemos el tamaño del array de parragrafos */
                            while (lastIndex2.indexOf("<picture>") > -1) {
                                   lastIndex2 = line2.substring(lastIndex2.indexOf("<picture>")+"<picture>".length(),lastIndex2.length());
                                   count2++;
                            }
     
                            picture_path = new String[count2]; 
                            /* Rellenamos el array de parragrafos con los parrafos*/
                            for(int u = 0; u<picture_path.length; u++){
                                   picture_path[u] = line2.substring(line2.indexOf("<picture>")+9, line2.indexOf("</picture>"));  
                                   line2 = line2.substring((line2.indexOf("</picture>")+10),line2.length());                             
                           }
                                
                        }
                    
                        N = new NewsClass(title, paragraph, picture_path);
                      
                        ResultList.add(N);
                        /* Lo encapsulamos en el resultado */
                        result.setResult(ResultList);
                        /* Resultado correcto*/
                        result.setOk(true);
                } 
                
              }catch (XMLDBException ex) {
                        result.setErrorMsg("Error al ejecutar la consulta!");
                        result.setException(ex);
                        result.setOk(false);
             }          
        }
        
        if((actionId.substring(0,1)).equalsIgnoreCase("I")){ /* Es un insert */
       
             /* Obtenemos la query a realizar */
              QUERY = Actions.getProperty(actionId);
              /* Inicializamos el queryservice*/
              XUpdateQueryService Update;
            try {
                Update = (XUpdateQueryService) c.getService("XUpdateQueryService", "1.0");
                 /* Obtenemos los parametros de la query */
                parameter = aDBAction.getParameters();
                /* Le introducimos los parametros a la query */
                FinalQuery = MessageFormat.format(QUERY, parameter); 
                log.info(FinalQuery);
                /* Ejecutamos la finalquery i la guardamos en un ResourceSet */
                Update.update(FinalQuery);
            } catch (XMLDBException ex) {
                Logger.getLogger(DBManagerClass.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        if(!((actionId.substring(0,1)).equalsIgnoreCase("Q")) && !((actionId.substring(0,1)).equalsIgnoreCase("I")) ){
            /* No ess ni una query ni un update, error! */
            result.setErrorMsg("Error, formato erróneo de las propiedades !");
            result.setOk(false);
        }
           
        return result;
    }
      
}